#ifndef _VL_RTSP_CONTEXT__H_
#define _VL_RTSP_CONTEXT__H_

#include "defs.h"
#include "media_session.h"
#include "rtsp_connection.h"
#include "utils/sync_code.h"
#include <unordered_map>

namespace VLRTSP {

/**
 * @Author: CimZzz
 * @Date: 2022-01-12 22:50:58
 * 
 * 声明 RTSP Server
 */
class RTSPServer;

class RTSPContext {
public:
	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-12 22:50:12
	 * 
	 * 构造函数
	 */
	explicit RTSPContext();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-12 22:50:16
	 * 
	 * 析构函数
	 */
	~RTSPContext();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-12 22:55:43
	 * 
	 * 检测媒体会话是否存在
	 * @param sessionId 媒体会话 Id
	 * @return 如果存在返回媒体会话指针，否则返回 nullptr
	 */
	std::shared_ptr<MediaSession> getMediaSession(const std::string& sessionId);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-14 17:13:51
	 * 
	 * 生成一个媒体数据分发器 Id
	 * @return 媒体分发器 Id
	 */
	uint32_t generateDispatcherId();

private:
	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-12 22:51:14
	 * 
	 * 声明 RTSP Server 为友元类
	 */
	friend class RTSPServer;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-14 17:48:40
	 * 
	 * 销毁并回收资源
	 */
	void _destroy();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-12 22:53:38
	 * 
	 * 添加 RTSP 链接
	 * @param connection RTSP 链接
	 */
	void _addRTSPConnection(std::shared_ptr<RTSPConnection>& connection);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-12 23:17:00
	 * 
	 * 移除 RTSP 链接
	 * @param connectionId 链接 Id
	 */
	void _removeRTSPConnection(uint32_t connectionId);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-12 22:54:39
	 * 
	 * 添加媒体会话
	 * @param session 媒体会话
	 * 
	 * @note 媒体会话 Id 在同一个 RTSP 服务器中必须唯一，否则将会抛出异常
	 */
	void _addMediaSession(MediaSession* session);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-14 19:14:18
	 * 
	 * 通过媒体资源会话 Id 和媒体资源 Id 找到媒体资源
	 * @param sessionId 媒体资源会话 Id
	 * @param sourceId 媒体资源 Id
	 * @return 媒体资源
	 */
	MediaSource* _findMediaSource(const std::string& sessionId, uint32_t sourceId);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-12 23:15:05
	 * 
	 * RTSP 链接操作锁
	 */
	std::mutex connMutex;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-12 22:56:48
	 * 
	 * 媒体会话资源操作锁
	 */
	std::mutex sessionMutex;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-14 17:14:22
	 * 
	 * 媒体分发器发号机
	 */
	SyncCode dispatcherCode;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-11 15:38:39
	 * 
	 * RTSP 链接映射表
	 */
	std::unordered_map< uint32_t, std::shared_ptr<RTSPConnection> > socketMap;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-10 19:50:21
	 * 
	 * 媒体会话映射表
	 */
	std::unordered_map< std::string, std::shared_ptr<MediaSession> > mediaSessionMap;
};

} 


#endif //_VL_RTSP_CONTEXT__H_
